package server

import (
	"net/http"
	"strconv"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
	"github.com/go-chi/render"

	"ctfo-platform-go/server/model"
	"ctfo-platform-go/server/service"
)

func newRouter() http.Handler {
	r := chi.NewRouter()

	r.Use(middleware.RequestID)
	r.Use(middleware.Logger)
	r.Use(middleware.Recoverer)
	r.Use(middleware.URLFormat)
	r.Use(render.SetContentType(render.ContentTypeJSON))

	r.Route("/users", func(r chi.Router) {
		var userService = service.NewUserService(db, rdb)

		r.Get("/", func(w http.ResponseWriter, r *http.Request) {
			urlQuery := r.URL.Query()

			users, err := userService.ListUsers(r.Context(), urlQuery.Get("name"))
			handle(w, r, users, err)
		})

		r.Get("/{id}", func(w http.ResponseWriter, r *http.Request) {
			id, _ := strconv.Atoi(chi.URLParam(r, "id"))
			user, err := userService.GetUserById(r.Context(), id)
			handle(w, r, user, err)
		})

		r.With(bindRequestBody((*model.UserPayload)(nil))).Post("/{id}/update", func(w http.ResponseWriter, r *http.Request) {
			id, _ := strconv.Atoi(chi.URLParam(r, "id"))
			userPayload := r.Context().Value(bindReqKey).(*model.UserPayload)

			err := userService.UpdateUser(r.Context(), id, *userPayload)
			handle(w, r, nil, err)
		})

		r.Post("/{id}/delete", func(w http.ResponseWriter, r *http.Request) {
			id, _ := strconv.Atoi(chi.URLParam(r, "id"))
			err := userService.DeleteUser(r.Context(), id)
			handle(w, r, nil, err)
		})

		r.With(paginate).Get("/page", func(w http.ResponseWriter, r *http.Request) {
			pageParam := r.Context().Value(pageContextKey).(model.PageParam)
			urlQuery := r.URL.Query()

			page, err := userService.PageUsers(r.Context(), pageParam, urlQuery.Get("name"))
			handle(w, r, page, err)
		})

		r.With(bindRequestBody((*model.UserPayload)(nil))).Post("/add", func(w http.ResponseWriter, r *http.Request) {
			userPayload := r.Context().Value(bindReqKey).(*model.UserPayload)
			err := userService.AddUser(r.Context(), *userPayload)
			handle(w, r, nil, err)
		})

	})

	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("health:ok"))
	})

	return r
}
